Tutoriel Gtk2Hs

Tutoriel Gtk2Hs 3.1 - Empaquetage des widgets

Lorsque vous voudrez créer une application, vous voudrez mettre plus qu'un seul widget dans une fenêtre. Notre premier exemple "hello world" utilise seulement un widget et on pouvait simplement utiliser set pour spécifier le containerChild widget pour window, ou utiliser containerAdd pour "empaqueter" le widget dans la fenêtre. Mais lorsque vous voudrez mettre plus qu'un seul widget dans une fenêtre, comment contrôler où ces widgets seront positionnés? C'est là qu'intervient : l'empaquetage.

Théorie de l'empaquetage des boites

La plupart des empaquetages sont réalisés en créant des boites. Ce sont des widgets "conteneurs" invisibles que l'on peut remplir avec nos widgets et qui sont disponibles sous deux formes: une boite horizontale ou verticale. Lorsque l'on empaquette les widgets dans une boite horizontale, les objets sont insérés de gauche à droite ou de droite à gauche suivant l'appel utilisé. Dans une boite verticale, les widgets sont empaquetés du haut vers le bas ou inversement. On peut utiliser n'importe quelle combinaison de boites à l'intérieur ou à l'extérieur d'autres boites pour créer l'effet désiré.

Pour créer une boite horizontale, on utilise hBoxNew, et pour une boite verticale vBoxNew. Chaque fonction prend comme argument un Bool et un Int. Le premier paramètre donne à tous les enfants un espacement égal s’il est défini à True et le deuxième donne l'espace en pixels par défaut entre les enfants.

Les fonctions boxPackStart et boxPackEnd sont utilisées pour placer des objets à l'intérieur de ces conteneurs. La fonction boxPackStart commence en haut et va vers le bas dans une VBox, commence à gauche et va vers la droite dans une HBox. L'utilisation de ces fonctions permet de justifier à droite ou à gauche et peuvent être combinées de n'importe quelle manière pour obtenir l'effet escompté. Dans la plupart des exemples, nous utiliserons boxPackStart.

Un objet peut être un autre conteneur ou un widget. Dans la réalité, beaucoup de widgets sont des conteneurs eux-mêmes, comme button, mais on utilise généralement seulement un label à l'intérieur d'un button.

Gtk
 
Gtk2Hs
 
Packed
 
buttons

import Graphics.UI.Gtk

main :: IO ()
main = do
  initGUI
  window  <- windowNew
  hbox    <- hBoxNew True 10
  button1 <- buttonNewWithLabel "Button 1"
  button2 <- buttonNewWithLabel "Button 2"
  set window [windowDefaultWidth := 200, windowDefaultHeight := 200,
              containerBorderWidth := 10, containerChild := hbox]
  boxPackStart hbox button1 PackGrow 0
  boxPackStart hbox button2 PackGrow 0
  onDestroy window mainQuit
  widgetShowAll window
  mainGUI

En utilisant boxPackStart ou boxPackEnd, Gtk sait où vous voulez placer votre widget, il peut alors modifier leur taille automatiquement et d'autres choses sympathiques.

boxPackStart :: (WidgetClass child, BoxClass self) => self -> child -> Packing -> Int -> IO ()
boxPackEnd :: (WidgetClass child, BoxClass self) => self -> child -> Packing -> Int -> IO ()

Le paramètre Packing spécifie la façon dont les widgets dans le conteneur se comportent quand la fenêtre est redimensionnée. PackNatural signifie que les widgets garderont leur taille et resteront ou ils se trouvent, PackGrow signifie qu'ils seront redimensionnés, et PackRepel signifie que les widgets seront également répartis des deux cotés. Le dernier paramètre est un Int qui spécifie l'espace additionnel à mettre entre cet enfant et ses voisins.

Notez que Packing s'applique uniquement à la dimension de la boite. Si, par exemple, vous spécifiez PackNatural au lieu de PackGrow dans l'exemple ci-dessus, le redimensionnement horizontal gardera les boutons à leur place originale, mais le redimensionnement vertical va changer la taille des boutons. Ceci est dû au fait que les boutons sont placés de façon homogène dans la boite horizontale (Le premier paramètre est True) et la boite elle-même sera redimensionnée avec la fenêtre. L'exemple qui va suivre montrera cela de façon plus claire.